import 'package:json_annotation/json_annotation.dart';

part 'photo_model.g.dart';

/// u7167u7247u6a21u578b
@JsonSerializable()
class PhotoModel {
  /// u7167u7247ID
  final String id;

  /// u6240u5c5eu76f8u518cID
  @JsonKey(name: 'album_id')
  final String albumId;

  /// u7167u7247URL
  final String? url;

  /// u7f29u7565u56feURL
  @JsonKey(name: 'thumbnail_url')
  final String? thumbnailUrl;

  /// u7167u7247u540du79f0
  final String? name;

  /// u7167u7247u63cfu8ff0
  final String? description;

  /// u672cu5730u8defu5f84uff08u53efu9009uff0cu53eau5728u672cu5730u4f7fu7528uff09
  @JsonKey(includeIfNull: false)
  final String? localPath;

  /// u4e0au4f20u72b6u6001uff08u672au4e0au4f20u3001u4e0au4f20u4e2du3001u5df2u4e0au4f20uff09
  @JsonKey(name: 'upload_status')
  final UploadStatus? uploadStatus;

  /// u62cdu6444u65f6u95f4
  @JsonKey(name: 'taken_at')
  final DateTime? takenAt;

  /// u521bu5efau65f6u95f4
  @JsonKey(name: 'created_at')
  final DateTime createdAt;

  /// u66f4u65b0u65f6u95f4
  @JsonKey(name: 'updated_at')
  final DateTime updatedAt;

  /// u7167u7247u5bbdu5ea6
  final int? width;

  /// u7167u7247u9ad8u5ea6
  final int? height;

  /// u6587u4ef6u5927u5c0fuff08u5b57u8282uff09
  @JsonKey(name: 'file_size')
  final int? fileSize;

  /// u6587u4ef6u7c7bu578buff08MIMEu7c7bu578buff09
  @JsonKey(name: 'mime_type')
  final String? mimeType;

  /// u6784u9020u51fdu6570
  PhotoModel({
    required this.id,
    required this.albumId,
    this.url,
    this.thumbnailUrl,
    this.name,
    this.description,
    this.localPath,
    this.uploadStatus,
    this.takenAt,
    required this.createdAt,
    required this.updatedAt,
    this.width,
    this.height,
    this.fileSize,
    this.mimeType,
  });

  /// u4ece JSON u521bu5efau5bf9u8c61
  factory PhotoModel.fromJson(Map<String, dynamic> json) => PhotoModel(
        id: json['id'] as String,
        albumId: json['album_id'] as String,
        url: json['url'] as String?,
        thumbnailUrl: json['thumbnail_url'] as String?,
        name: json['name'] as String?,
        description: json['description'] as String?,
        localPath: json['local_path'] as String?,
        uploadStatus: _parseUploadStatus(json['upload_status']),
        takenAt: json['taken_at'] != null
            ? DateTime.parse(json['taken_at'] as String)
            : null,
        createdAt: DateTime.parse(json['created_at'] as String),
        updatedAt: DateTime.parse(json['updated_at'] as String),
        width: json['width'] as int?,
        height: json['height'] as int?,
        fileSize: json['file_size'] as int?,
        mimeType: json['mime_type'] as String?,
      );

  /// u8f6cu6362u4e3a JSON
  Map<String, dynamic> toJson() => {
        'id': id,
        'album_id': albumId,
        'url': url,
        'thumbnail_url': thumbnailUrl,
        'name': name,
        'description': description,
        'local_path': localPath,
        'upload_status': uploadStatus?.toString().split('.').last,
        'taken_at': takenAt?.toIso8601String(),
        'created_at': createdAt.toIso8601String(),
        'updated_at': updatedAt.toIso8601String(),
        'width': width,
        'height': height,
        'file_size': fileSize,
        'mime_type': mimeType,
      };

  /// u89e3u6790u4e0au4f20u72b6u6001
  static UploadStatus? _parseUploadStatus(dynamic value) {
    if (value == null) return null;

    final statusStr = value.toString();
    for (final status in UploadStatus.values) {
      if (status.toString().split('.').last == statusStr) {
        return status;
      }
    }
    return null;
  }

  /// u4eceu672cu5730u6587u4ef6u521bu5efau7167u7247u6a21u578b
  factory PhotoModel.fromLocalFile({
    required String albumId,
    required String localPath,
    String? name,
    DateTime? takenAt,
    int? width,
    int? height,
    int? fileSize,
    String? mimeType,
  }) {
    final id = DateTime.now().millisecondsSinceEpoch.toString();
    return PhotoModel(
      id: id,
      albumId: albumId,
      url: '', // u672au4e0au4f20u524du4e3au7a7a
      thumbnailUrl: '', // u672au4e0au4f20u524du4e3au7a7a
      name: name ?? localPath.split('/').last,
      localPath: localPath,
      uploadStatus: UploadStatus.pending,
      takenAt: takenAt ?? DateTime.now(),
      createdAt: DateTime.now(),
      updatedAt: DateTime.now(),
      width: width,
      height: height,
      fileSize: fileSize,
      mimeType: mimeType,
    );
  }

  /// u590du5236u5e76u66f4u65b0u5c5eu6027
  PhotoModel copyWith({
    String? url,
    String? thumbnailUrl,
    String? name,
    String? description,
    String? localPath,
    UploadStatus? uploadStatus,
    DateTime? takenAt,
    int? width,
    int? height,
    int? fileSize,
    String? mimeType,
  }) {
    return PhotoModel(
      id: this.id,
      albumId: this.albumId,
      url: url ?? this.url,
      thumbnailUrl: thumbnailUrl ?? this.thumbnailUrl,
      name: name ?? this.name,
      description: description ?? this.description,
      localPath: localPath ?? this.localPath,
      uploadStatus: uploadStatus ?? this.uploadStatus,
      takenAt: takenAt ?? this.takenAt,
      createdAt: this.createdAt,
      updatedAt: this.updatedAt,
      width: width ?? this.width,
      height: height ?? this.height,
      fileSize: fileSize ?? this.fileSize,
      mimeType: mimeType ?? this.mimeType,
    );
  }
}

/// u7167u7247u4e0au4f20u72b6u6001
enum UploadStatus {
  /// u672au4e0au4f20
  @JsonValue('pending')
  pending,

  /// u4e0au4f20u4e2d
  @JsonValue('uploading')
  uploading,

  /// u4e0au4f20u5931u8d25
  @JsonValue('failed')
  failed,

  /// u5df2u4e0au4f20
  @JsonValue('uploaded')
  uploaded,
}
